package com.jxzn.locust.controller.admin;

import java.util.Calendar;
import java.util.List;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jxzn.locust.dto.ResultDTO;
import com.jxzn.locust.model.AbstractNamedModel;
import com.jxzn.locust.service.AbstractService;
import com.jxzn.locust.support.Auth;
import com.jxzn.locust.support.OperateAction;

public abstract class NamedEntityController<T extends AbstractNamedModel> {

    public abstract AbstractService<T> getService();

    public abstract String getFolder();

    /**
     * 去列表页
     * 
     * @param model
     * @param query
     * @return
     */
    @RequestMapping("/list")
    @Auth(action = OperateAction.VIEW)
    public String findAll(HttpServletRequest request, Model model, T query) {
        query.setDeleted(Boolean.FALSE);
        beforeGotoList(query);
        List<T> dataList = getService().findAll(query);
        model.addAttribute("dataList", dataList);
        model.addAttribute("query", query);
        beforeGotoSearch(request, model, dataList);
        return "/bg/" + getFolder() + "/list";
    }

    /**
     * 跳转到搜索页面之前添加一些搜索条件字典，如下拉框等数据
     * 
     * @param model
     */
    public void beforeGotoSearch(HttpServletRequest request, Model model, List<T> tList) {

    }

    public void beforeGotoList(T query) {
    }

    /**
     * 去编辑页面
     * 
     * @param model
     * @param id
     * @return
     */
    @GetMapping("/edit")
    @Auth(action = OperateAction.VIEW)
    public String edit(HttpServletRequest request, Model model, T query, @RequestParam(value = "id", required = false, defaultValue = "0") int id) {
        String action = "添加";
        if (id > 0) {
            Optional<T> optional = getService().findById(id);
            if (optional.isPresent()) {
                model.addAttribute("target", optional.get());
                action = "编辑";
            }
        }
        beforeGotoEdit(request, model, query, id);
        model.addAttribute("query", query);
        model.addAttribute("action", action);
        return "/bg/" + getFolder() + "/edit";
    }

    /**
     * 跳转到编辑页面前增加自定义数据
     * 
     * @param model
     * @param query
     * @param id
     */
    public void beforeGotoEdit(HttpServletRequest request, Model model, T query, int id) {

    }

    public void beforeSave(T query) {
    }

    /**
     * 添加/保存，存在同名的就不保存了
     * 
     * @param query
     * @param model
     * @return
     */
    @PostMapping("/edit")
    @ResponseBody
    @Auth(action = OperateAction.EDIT)
    public String edit(HttpServletRequest request, T query, Model model) {
        query.setDeleted(Boolean.FALSE);
        if (null == query.getId()) {
            Optional<T> optional = getService().getOne(query);
            if (optional.isPresent()) {
                return findAll(request, model, query);
            }
        } else {
            query.setUpdateTime(Calendar.getInstance().getTime());
        }
        beforeSave(query);
        getService().save(query);
        return "redirect:" + findAll(request, model, query);
    }

    /**
     * 添加/保存，存在同名的就不保存了
     * 
     * @param query
     * @param model
     * @return
     */
    @PostMapping("/edit/repeatable")
    @ResponseBody
    @Auth(action = OperateAction.EDIT)
    public ResultDTO<?> editRepeatable(T query, Model model) {
        query.setDeleted(Boolean.FALSE);
        if (null != query.getId()) {
            query.setUpdateTime(Calendar.getInstance().getTime());
        }
        beforeSave(query);
        getService().save(query);
        return ResultDTO.success();
    }

    /**
     * 保存，并返回json对象
     * 
     * @param query
     * @param model
     * @return
     */
    @PostMapping("/edit2")
    @ResponseBody
    @Auth(action = OperateAction.EDIT)
    public ResultDTO<?> edit2(T query, Model model) {
        query.setDeleted(Boolean.FALSE);
        if (null == query.getId()) {
            Optional<T> optional = getService().getOne(query);
            if (optional.isPresent()) {
                return ResultDTO.success();
            }
        } else {
            query.setUpdateTime(Calendar.getInstance().getTime());
        }
        beforeSave(query);
        getService().save(query);
        return ResultDTO.success();
    }

    /**
     * 删除
     * 
     * @param id
     * @param model
     * @return
     */
    @PostMapping("/delete")
    @ResponseBody
    @Auth(action = OperateAction.DELETE)
    public ResultDTO<?> add(@RequestParam("id") int id, Model model) {
        Optional<T> optional = getService().findById(id);
        if (!optional.isPresent()) {
            return ResultDTO.success();
        }
        T target = optional.get();
        target.setDeleted(Boolean.TRUE);
        target.setUpdateTime(Calendar.getInstance().getTime());
        getService().update(target);
        afterDeleted(target);
        return ResultDTO.success();
    }

    public void afterDeleted(T t) {
    }
}
